home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group99a.txt
/
000043_icon-group-sender _Thu Feb 25 12:32:44 1999.msg
< prev
next >
Wrap
Internet Message Format
|
2000-09-20
|
7KB
Return-Path: <icon-group-sender>
Received: (from root@localhost)
by baskerville.CS.Arizona.EDU (8.9.1a/8.9.1) id MAA12131
for icon-group-addresses; Thu, 25 Feb 1999 12:30:44 -0700 (MST)
Message-Id: <199902251930.MAA12131@baskerville.CS.Arizona.EDU>
From: "Frank Lhota" <lhotaf@lexma.meitech.com>
To: <icon-group@optima.CS.Arizona.EDU>
Subject: Designing the Bridge between Icon and C
Date: Thu, 25 Feb 1999 13:04:29 -0500
X-Priority: 3
X-MSMail-Priority: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V4.71.1712.3
Errors-To: icon-group-errors@optima.CS.Arizona.EDU
Status: RO
As I mentioned in a previous posting, I would like to develop an Icon
facility for calling a native C function in a dynamic library, that is, a C
function that is not an Icon "wrapper" function. I believe this can be done
in reasonably flexible and portable way. In my proposed design, a C function
is loaded into Icon using the predefined function loadfunc, which takes the
form
loadfunc ( modname, funcname, conv )
where
- modname is the name of the dynamic library file,
- funcname is the name of the function as it appears in the library; and
- conv is a string indicating the calling convention ("C" or "Pascal"); the
conv parameter defaults to "C".
The loaded external C function is called using the callout function, invoked
as follows:
callout ( funcname, retval, argv[] )
where
- funcname is the name of the external function;
- retval is a prototype for the return value (defaults to &null, indicating
that the C function return type is void); and
- argv[] is the list of function arguments, which are to be converted to C
format before the procedure is called.
To free the resources associated with loaded C function, call the Icon
function unloadfunc, called with the name of the loaded function:
unloadfunc(funcname)
The real sticking point is how to design the Icon specification of C data.
Icon is relatively free of the data representation concerns that pervade C.
Part of what we need to do when we to convert Icon data to C is to add a
specification on how this data is to be represented.
All C types fall into two categories: basic types and derived types. The
basic data types of C can be divided into three categories:
1. The void type;
2. The integer types, including char, short, int, and long (as well as
long long on some systems), along with their unsigned versions; and
3. The floating point types float, double, and on some systems, long
double.
Since enumerations always have integral values, we can include enumeration
types with the integer types.
Representing the C void is easy. The Icon null type is the perfect
counterpart to the C void type.
Integers and floats are more problematic. Icon is not concerned with number
sizes, and Icon integers always have a sign. An Icon real can be directly be
translated into a C double. An Icon integer can also be used to represent a
signed C int. To translate Icon to other C numeric types, we need some way
to specify the number format. To do this, I propose a standard Icon include
file that defines the following Icon record types:
record int ( value, size, unsigned )
record float ( value, size )
When records of these types are used as callout parameters, they have the
following meanings:
- A record of the form int ( value, size, unsigned ) represents a C integer
with a value given by the value component and with a length of size bytes.
This C integer is unsigned if the unsigned component of the record is
non-null.
- A record of the form float ( value, size ) represents a C real number with
a value given by the value component of length of size bytes.
These numeric formatting records should suffice for specifying any of the
basic C numeric types.
Generating the C derived types from Icon is a bit more challenging. Starting
with the basic C types, all C types can be derived using the following
constructs:
1. An array of objects of a given type;
2. A structure containing a sequence of objects of various types;
3. A union that is capable of containing any one of several objects of
various types;
4. A pointer to an object of a given type; or
5. A pointer to a function.
The Icon representation of a C array or structure is relatively
straightforward. From a certain point of view, an array is quite similar to
a structure. Both an array and a structure are a sequence of values; the
difference is that in an array, the values are all of the same type. A C
array or structure can be modeled in Icon using an Icon list. When callout
translates an Icon list to C, it will create a C region consisting of a
sequence of the C translations of the elements in the Icon list. The int and
float record types can be used to specify structure member sizes.
One of the most popular C arrays are, of course, arrays of characters. We
should be able to use Icon strings to represent C strings.
Representing a C union in Icon is trickier, since there is no obvious Icon
equivalent. Some important API functions use unions, so we should come up
with some way of representing them in Icon. For now, I'm stumpted on this
one. I would greatly appreciate anyone's input on this matter.
Pointers are very important. This is how C implements "call by reference".
For many C functions, the most important outputs are returned by pointers.
Icon technically uses only "call by value", but the effect of "call by
reference" can be obtained by using Icon structures. We can therefore get
the desired effect using the following record types:
record Pointer ( value )
record CPointer ( value )
In the context of callout, a Pointer record represents a pointer to the C
representation of the value component. When callout encounters a record of
this type, it will allocate a C region to store the C translation of the
Icon value. The pointer to this C region can then be used in the call to the
C function. After the C function is called, the region value can then be
copied back to the Pointer record, and the pointer is deallocated. For
example,
# function bar declared as
# void bar ( int *ip );
callout ( "bar", &null, ip := Pointer ( 0 ) )
# ip.value updated by callout
The CPointer record is similar to pointer, except that it is used to
indicate a pointer to a region that will not be modified by the C function.
The callout function processes a CPointer record in the same way, except
that the region value is not copied back to pointer value.
For now, I'm punting on coming up with an Icon representation of C function
pointers. Ideally, it would be nice to be able to automatically generate C
wrapper functions that call an Icon procedure, but that is a project for
another day.
I've started work on this interface design, but before I take it further, I
would greatly some feedback from the Icon programmer community. In
particular,
- Does this design meet your interface needs?
- Is there a simpler and/or more intuitive design for this interface?
- How would you implement C unions in Icon?